﻿using System.Collections;
using System.Threading;
using System;

namespace JN.Utility
{
    public class ThreadWrapper
    {
        private Thread _t;
        private string _name = "AsyncThreadService";
        private AutoResetEvent _waitAutoRstEvent = new AutoResetEvent(false);
        private ParameterizedThreadStart _workMethod;
        private Queue _threadArgsQueue;
        private bool _isRunning = false;
        private ThreadPriority _priority = ThreadPriority.Normal;

         
        public bool IsRunning
        {
            get { return _isRunning; }
        }
        public ThreadPriority Priority
        {
            get { return _priority; }
        }

        public ThreadWrapper(string threadName, ParameterizedThreadStart workMethod )
            : this(threadName, workMethod, true, ThreadPriority.Normal)
        {
        }

        public ThreadWrapper(string threadName, ParameterizedThreadStart workMethod,ThreadPriority priority)
            :this(threadName,workMethod,true,priority)
        { 
        }

        public ThreadWrapper(string threadName, ParameterizedThreadStart workMethod, bool isRunningImmediately,ThreadPriority priority)
        {
            _name = threadName;
            _workMethod = workMethod;
            _priority = priority;
            if (isRunningImmediately)
            {
                Start();
            }
        }

        public void Trigger(object objArgs)
        {
            if (_isRunning)
            {
                _threadArgsQueue.Enqueue(objArgs);
                _waitAutoRstEvent.Set();
            }
        }

        public void Start()
        {
            if (!_isRunning)
            {
                _isRunning = true;
                _threadArgsQueue = Queue.Synchronized(new Queue(10));
                _t = new Thread(WorkThreadWrapper);
                _t.Priority = _priority; 
                _t.Name = _name;
                _t.IsBackground = true;
                _t.Start(); 
            }
        }

        public void Stop()
        {
            try
            {
                _isRunning = false;
                _waitAutoRstEvent.Set();
                Thread.Sleep(10);
                _t.Abort();
            }
            catch
            { }
        }

        private void WorkThreadWrapper()
        {
            while (_isRunning)
            {
                _waitAutoRstEvent.WaitOne();
                if (!_isRunning)
                {
                    return ;
                }
                try
                {
                    while (_threadArgsQueue.Count > 0)
                    {
                        object threadArgs = _threadArgsQueue.Dequeue();
                        foreach (ParameterizedThreadStart methodCaller in _workMethod.GetInvocationList())
                        {
                            try
                            {
                                if (!_isRunning)
                                {
                                    return;
                                }
                                methodCaller(threadArgs);
                            }
                            catch
                            { }
                        }
                    }
                }
                catch
                {
                }
            }
        }
    }
}

